import * as fs from 'fs';
import * as path from 'path';
import * as vscode from 'vscode';


/**
 * CSS解析器类
 * 负责解析CSS文件并提取类名，包含缓存机制优化性能
 */
export class CSSParser {
    private cssClasses: Set<string> = new Set();
    private fileWatchers: vscode.FileSystemWatcher[] = [];
    private fileCache: Map<string, { classes: string[], mtime: number }> = new Map();
    private lastRefreshTime: number = 0;
    private refreshThrottleMs: number = 1000 * 1200; // 1秒内最多刷新一次

    constructor() {
        this.setupFileWatchers();
    }

    /**
     * 设置文件监听器
     */
    private setupFileWatchers(): void {
        // 监听CSS文件变化
        const cssWatcher = vscode.workspace.createFileSystemWatcher('**/*.css');
        cssWatcher.onDidChange(() => this.refreshCSSClasses());
        cssWatcher.onDidCreate(() => this.refreshCSSClasses());
        cssWatcher.onDidDelete(() => this.refreshCSSClasses());
        
        this.fileWatchers.push(cssWatcher);
    }

    /**
     * 解析指定的CSS文件并提取类名（带缓存）
     * @param filePath CSS文件路径
     * @returns 类名数组
     */
    public parseCSSFile(filePath: string): string[] {
        try {
            // 处理相对路径，转换为绝对路径
            let absolutePath = filePath;
            if (!path.isAbsolute(filePath)) {
                const workspaceRoot = vscode.workspace.workspaceFolders?.[0]?.uri.fsPath;
                if (workspaceRoot) {
                    absolutePath = path.join(workspaceRoot, filePath);
                }
            }
            
            if (!fs.existsSync(absolutePath)) {
                return [];
            }

            // 检查文件修改时间
            const stats = fs.statSync(absolutePath);
            const mtime = stats.mtime.getTime();
            
            // 检查缓存
            const cached = this.fileCache.get(absolutePath);
            if (cached && cached.mtime === mtime) {
                return cached.classes;
            }

            // 解析文件内容
            const content = fs.readFileSync(absolutePath, 'utf8');
            const classes = this.extractClassesFromContent(content);
            
            // 更新缓存
            this.fileCache.set(absolutePath, { classes, mtime });
            
            return classes;
        } catch (error) {
            console.error('解析CSS文件失败:', filePath, error);
            return [];
        }
    }

    /**
     * 从CSS内容中提取类名
     * @param content CSS文件内容
     * @returns 类名数组
     */
    private extractClassesFromContent(content: string): string[] {
        const classes: string[] = [];
        const classRegex = /\.([a-zA-Z][a-zA-Z0-9_-]*)/g;
        let match;

        while ((match = classRegex.exec(content)) !== null) {
            const className = match[1];
            if (className && !classes.includes(className)) {
                classes.push(className);
            }
        }

        return classes;
    }

    /**
     * 解析多个CSS文件
     * @param filePaths CSS文件路径数组
     * @returns 所有类名的集合
     */
    public parseCSSFiles(filePaths: string[]): Set<string> {
        const allClasses = new Set<string>();
        
        for (const filePath of filePaths) {
            const classes = this.parseCSSFile(filePath);
            classes.forEach(className => allClasses.add(className));
        }

        return allClasses;
    }

    /**
     * 刷新CSS类名缓存（带节流）
     */
    public async refreshCSSClasses(): Promise<void> {
        const now = Date.now();
        if (now - this.lastRefreshTime < this.refreshThrottleMs) {
            return; // 节流，避免频繁刷新
        }
        this.lastRefreshTime = now;
        
        const config = vscode.workspace.getConfiguration('css.helper');
        const styleSheets = config.get<string[]>('styleSheets', []);
        
        if (styleSheets.length > 0) {
            this.cssClasses = this.parseCSSFiles(styleSheets);
        } else {
            // 如果没有指定CSS文件，则扫描工作区中的所有CSS文件
            await this.scanWorkspaceCSSFiles();
        }
    }

    /**
     * 扫描工作区中的所有CSS文件
     */
    private async scanWorkspaceCSSFiles(): Promise<void> {
        try {
            // const cssFiles = await vscode.workspace.findFiles('**/*.css', '**/node_modules/**');
            const cssFiles = await vscode.workspace.findFiles('**/*.css');
            const filePaths = cssFiles.map(file => file.fsPath);
            this.cssClasses = this.parseCSSFiles(filePaths);
        } catch (error) {
            console.error('扫描CSS文件失败:', error);
        }
    }

    /**
     * 获取所有CSS类名
     * @returns CSS类名集合
     */
    public getCSSClasses(): Set<string> {
        return this.cssClasses;
    }

    /**
     * 根据前缀过滤CSS类名
     * @param prefix 前缀字符串
     * @returns 匹配前缀的类名数组
     */
    public getClassesByPrefix(prefix: string): string[] {
        return Array.from(this.cssClasses).filter(className => 
            className.startsWith(prefix)
        );
    }

    /**
     * 销毁文件监听器
     */
    public dispose(): void {
        this.fileWatchers.forEach(watcher => watcher.dispose());
        this.fileWatchers = [];
        this.fileCache.clear();
    }

    /**
     * 清理缓存
     */
    public clearCache(): void {
        this.fileCache.clear();
        this.cssClasses.clear();
    }

    /**
     * 获取缓存统计信息
     */
    public getCacheStats(): { fileCount: number, classCount: number } {
        return {
            fileCount: this.fileCache.size,
            classCount: this.cssClasses.size
        };
    }
}
